﻿#region - Class details -
/*  
 *  Developer   : Wicus Botha
 *  Description : 
 *  History     : WB - 2008-10-20 - Created
 */
#endregion

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using IQ.DbBase;


namespace SqlServerAdmin
{
    public class SqlMdTable : SqlMetaData
    {
        #region # Constructor #
        public SqlMdTable() : base()
        {
        }
        #endregion

        #region - Private variables -
        private DataTable dtServer;
        private DataTable dtServerFields;
        #endregion

        #region - Private methods -
        private FieldChangeType compareField(DataRow source, DataRow dest)
        {
            string sv = "";
            string dv = "";
            FieldChangeType change = FieldChangeType.NoChange;
            //if (Convert.ToInt32(source[SqlQueries.Field_ColumnId]) != Convert.ToInt32(dest[SqlQueries.Field_ColumnId]))
            //    change = FieldChangeType.OrderChange;
            sv = source[SqlQueries.Field_ColumnDefaultValue].ToString();
            dv = dest[SqlQueries.Field_ColumnDefaultValue].ToString();
            if (change == FieldChangeType.NoChange &&
                sv != dv)
                change = FieldChangeType.DefValue;
            //
            if (change == FieldChangeType.NoChange &&
                Convert.ToByte(source[SqlQueries.Field_ColumnIsNullable]) != Convert.ToByte(dest[SqlQueries.Field_ColumnIsNullable]))
                change = FieldChangeType.Nullable;
            //
            if (change == FieldChangeType.NoChange &&
                source[SqlQueries.Field_ColumnFieldType].ToString() != dest[SqlQueries.Field_ColumnFieldType].ToString())
                change = FieldChangeType.DataType;
            //
            if (change == FieldChangeType.NoChange &&
                Convert.ToInt32(source[SqlQueries.Field_ColumnLength]) != Convert.ToInt32(dest[SqlQueries.Field_ColumnLength]))
                change = FieldChangeType.Length;
            //
            if (change == FieldChangeType.NoChange &&
                source[SqlQueries.Field_ColumnPrecision].ToString() != dest[SqlQueries.Field_ColumnPrecision].ToString())
                change = FieldChangeType.Precision;
            //
            if (change == FieldChangeType.NoChange &&
                source[SqlQueries.Field_ColumnScale].ToString() != dest[SqlQueries.Field_ColumnScale].ToString())
                change = FieldChangeType.Scale;
            //
            if (change == FieldChangeType.NoChange &&
                 Convert.ToByte(source[SqlQueries.Field_ColumnIsIdentity]) != Convert.ToByte(dest[SqlQueries.Field_ColumnIsIdentity]))
                change = FieldChangeType.ColStat;
            //
            return change;
        }
        private bool checkForDeleteFields(string tableId)
        {
            bool result = false;
            DataRow[] serverFields = dtServerFields.Select(SqlQueries.Field_TableId + "=" + tableId);
            foreach (DataRow dr in serverFields)
            {
                tmpFields.DefaultView.RowFilter = SqlQueries.Field_ColumnName + "='" + dr[SqlQueries.Field_ColumnName].ToString() + "'";
                if (tmpFields.DefaultView.Count == 0)
                {
                    DataRow newRow = tmpFields.NewRow();
                    newRow[SqlQueries.Field_ColumnName] = dr[SqlQueries.Field_ColumnName].ToString();
                    newRow["CompareIt"] = (byte)FieldChangeType.Deleted;
                    tmpFields.Rows.Add(newRow);
                    result = true;
                }
            }
            tmpFields.DefaultView.RowFilter = "";
            return result;
        }
        private void copyFileFieldsToTemp(string tableId)
        {
            if (tmpFields == null)
                createTempFields(SqlMdFileData.Instance.FileFields);
            DataTable fileFields = SqlMdFileData.Instance.FileFields;
            fileFields.DefaultView.RowFilter = SqlQueries.Field_TableId + "=" + tableId;
            tmpFields.Rows.Clear();
            foreach (DataRowView dr in fileFields.DefaultView)
            {
                DataRow newRow = tmpFields.NewRow();
                for (int i = 0; i < tmpFields.Columns.Count; ++i)
                {
                    if (fileFields.Columns.IndexOf(tmpFields.Columns[i].ColumnName) != -1)
                    {
                        string fVal = dr[i].ToString();
                        newRow[i] = dr[i];
                    }
                    newRow["CompareIt"] = 0;
                }
                tmpFields.Rows.Add(newRow);
                //tmpFields.AcceptChanges();                    
            }
        }
        #endregion

        //#region - Protected variables -
        //#endregion

        #region - Protected methods -
        protected override void loadServerData()
        {
            dtServer = DbHelper.Load_Table(SqlQueries.GetSqlMdSystemObjects(SqlQueries.SoT_Tables));
            dtServerFields = DbHelper.Load_Table(SqlQueries.GetSqlMdTableFields());
        }
        #endregion

        #region - Public properties / variables -
        public DataTable FileTables
        {
            get { return SqlMdFileData.Instance.FileTables; }
        }
        public DataTable ServerTables
        {
            get { return dtServer; }
        }
        #endregion

        #region - Public methods -
        /// <summary>
        /// This method is just a wrapper to be used in the loop of CompareAll
        /// </summary>
        /// <param name="type">not used</param>
        /// <param name="tableName">Table name to compare</param>
        /// <returns>True is equal, else False</returns>
        public bool CompareATable(string type, string tableName)
        {
            return this.CompareTable(tableName);
        }
        public DataView ServerTableFields(string tableName)
        {
            DataRow drServer = dtServer.Select(SqlQueries.Field_Name + "='" + tableName + "'").FirstOrDefault();
            if (drServer != null)
            {
                string tableId = drServer[SqlQueries.Field_Id].ToString();
                DataView serverFields = new DataView(dtServerFields, SqlQueries.Field_TableId + "=" + tableId,
                    SqlQueries.Field_ColumnId, DataViewRowState.CurrentRows);
                return serverFields;
            }
            return null;
        }
        public DataView FileTableFields(string tableName)
        {
            DataRow drFile = FileTables.Select(SqlQueries.Field_Name + "='" + tableName + "'").FirstOrDefault();
            if (drFile != null)
            {
                string tableId = drFile[SqlQueries.Field_Id].ToString();
                DataView tableFields = new DataView(SqlMdFileData.Instance.FileFields, SqlQueries.Field_TableId + "=" + tableId,
                    SqlQueries.Field_ColumnId, DataViewRowState.CurrentRows);
                return tableFields;
            }
            return null;
        }
        public bool CompareTable(string tableName)
        {
            bool tblChanged = false;
            // Get Server Table details
            DataRow drServer = dtServer.Select(SqlQueries.Field_Name + "='" + tableName + "'").FirstOrDefault();
            DataRow drFile = FileTables.Select(SqlQueries.Field_Name + "='" + tableName + "'").FirstOrDefault();
            if (drServer != null && drFile != null)
            {
                // Get File Table details
                string serverId = drServer[SqlQueries.Field_Id].ToString();
                DataView serverFields = new DataView(dtServerFields, SqlQueries.Field_TableId + "=" + serverId,
                    SqlQueries.Field_ColumnId, DataViewRowState.CurrentRows);
                copyFileFieldsToTemp(drFile[SqlQueries.Field_Id].ToString());
                //foreach (DataRow dr in tmpFields.Rows)
                for (int i = 0; i < tmpFields.Rows.Count; ++i)
                {
                    // Get Server field name  
                    DataRow serverField = dtServerFields.Select(SqlQueries.Field_TableId + "=" + serverId +
                        " AND " + SqlQueries.Field_ColumnName + "='" + tmpFields.Rows[i][SqlQueries.Field_ColumnName].ToString() + "'").FirstOrDefault();
                    if (serverField != null)
                    {
                        FieldChangeType change = compareField(tmpFields.Rows[i], serverField);
                        // Check colorder
                        if (change == FieldChangeType.NoChange && serverFields.Count > i)
                        {
                            if (tmpFields.Rows[i][SqlQueries.Field_ColumnName].ToString() != serverFields[i][SqlQueries.Field_ColumnName].ToString())
                                change = FieldChangeType.OrderChange;
                        }
                        if (change != FieldChangeType.NoChange)
                        {
                            tmpFields.Rows[i]["CompareIt"] = (byte)change;
                            tblChanged = true;
                        }
                    }
                    else
                    {
                        tmpFields.Rows[i]["CompareIt"] = (byte)FieldChangeType.NewField;
                        tblChanged = true;
                    }
                }
                //
                bool check = checkForDeleteFields(serverId);
                if (tblChanged || check)
                    addToChanges(tableName, ChangeType.Changed);
            }
            else
            {
                addToChanges(tableName, ChangeType.NotExistOnServer);
                tblChanged = true;
            }
            return tblChanged;
        }
        public void CompareAllTables()
        {
            compareAll(SqlQueries.SoT_Tables, CompareATable);
        }
        #endregion
    }
}
